import { KHashTable, KPair, numcmp, numhash, pad0 } from "@coldcloude/kai2";
import { Anime, GraphicInfo, Map } from "./crack-cg.js";
import { MapInfo, packMapInfo, packSpriteAnimeCollection, SpriteAnimeCollectionInfo } from "../hp3-pack.js";

export function packAllSprites(graphicInfos:GraphicInfo[],animes:Anime[],graphicDir:string,outputDir:string,start:number,end:number,outputInfo:boolean,outputAtlas:boolean){
    const giMap = new KHashTable<number,GraphicInfo>(numcmp,numhash);
    for(const gi of graphicInfos){
        giMap.set(gi.id,gi);
    }
    for(const anime of animes){
        const id = anime.info.id;
        if((start<0||id>=start)&&(end<0||id<end)){
            //build info
            const aniColle:SpriteAnimeCollectionInfo = {
                id: pad0(id,6),
                animes: [],
                frames: []
            }
            const gSet = new KHashTable<number,void>(numcmp,numhash);
            for(const single of anime.singles){
                //add anime
                const frameIds:string[] = [];
                for(const f of single.frames){
                    frameIds.push(pad0(f,6));
                }
                aniColle.animes.push({
                    direction: single.header.direction,
                    action: single.header.action,
                    duration: single.header.duration,
                    frameIds: frameIds
                });
                //add frames
                for(const f of single.frames){
                    gSet.compute(f,(kvp:KPair<number,void>|undefined)=>{
                        if(kvp===undefined){
                            kvp = {
                                key: f,
                                value: undefined
                            };
                            const gi = giMap.get(f);
                            if(gi!==undefined){
                                aniColle.frames.push({
                                    id: pad0(gi.id,6),
                                    positionX: gi.positionX,
                                    positionY: -gi.positionY-gi.height,
                                    width: gi.width,
                                    height: gi.height
                                });
                            }
                        }
                        return kvp;
                    });
                }
            }
            //pack
            console.log("processing "+aniColle.id+": "+aniColle.animes.length+" animes, "+aniColle.frames.length+" frames");
            packSpriteAnimeCollection(aniColle,graphicDir,outputDir,outputInfo,outputAtlas);
        }
    }
}

export function packMap(map:Map,graphicDir:string,outputDir:string,outputInfo:boolean,outputAtlas:boolean,outputTileMap:boolean){
    const mapInfo:MapInfo = {
        name: map.id,
        tileWidth: 64,
        tileHeight: 46,
        gridWidth: map.width,
        gridHeight: map.height,
        layers: [
            {
                name: "tiles",
                type: "tile",
                grids: map.tiles
            },
            {
                name: "objects",
                type: "object",
                grids: map.objects
            },
            {
                name: "tags",
                type: "tag",
                grids: map.tags
            },
            {
                name: "flags",
                type: "tag",
                grids: map.flags
            }
        ],
        tiles: [],
        objects: []
    }
    for(const gi of map.tileGraphics){
        mapInfo.tiles.push({
            id: pad0(gi.id,6),
            positionX: gi.positionX,
            positionY: -gi.positionY-gi.height,
            width: gi.width,
            height: gi.height,
            mapId: gi.mapId,
            gridWidth: gi.gridWidth,
            gridHeight: gi.gridHeight
        });
    }
    for(const gi of map.objectGraphics){
        mapInfo.objects.push({
            id: pad0(gi.id,6),
            positionX: gi.positionX,
            positionY: -gi.positionY-gi.height,
            width: gi.width,
            height: gi.height,
            mapId: gi.mapId,
            gridWidth: gi.gridWidth,
            gridHeight: gi.gridHeight
        });
    }
    //pack
    console.log("processing map "+map.id);
    packMapInfo(mapInfo,graphicDir,outputDir,outputInfo,outputAtlas,outputTileMap);
}
